package de.ars.client.datahandling;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Hashtable;
import java.util.Enumeration;
import java.util.Stack;
import java.util.Vector;

import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
import javax.microedition.rms.RecordEnumeration;
import javax.microedition.rms.RecordStore;

import de.ars.common.IDataModelConstants;

public class DataMangementSystem
{
    public static void saveDataToRS( final String name, final byte[] data )
    {
        RecordStore rms = null;
        try
        {
            RecordStore.deleteRecordStore( name );
        }
        catch( Exception e )
        {
        }

        try
        {
            rms = RecordStore.openRecordStore( name, true );
            rms.addRecord( data, 0, data.length );
        }
        catch( Exception e )
        {
        }
        finally
        {
            if( rms != null )
            {
                try
                {
                    rms.closeRecordStore();
                }
                catch( Exception e )
                {
                }
            }
        }
    }

    public static byte[] loadDataFromRS( final String name )
    {
        byte[] result = null;

        try
        {
            RecordStore rms = RecordStore.openRecordStore( name, false );

            if( rms.getNumRecords() > 0 )
            {
                RecordEnumeration records = rms.enumerateRecords( null, null, false );
                result = records.nextRecord();
            }

            rms.closeRecordStore();
        }
        catch( Exception e )
        {
            result = null;
        }

        return result;
    }

    public static Hashtable loadInformationGroup()
    {
        return new InformationGroupLoader( IDataModelConstants.RESOURCE_PATH ).loadFromFile();
    }
    
    public static void DEBUG_createDirectory( String path, String file )
    {
        try
        {
            FileConnection fconn = (FileConnection)Connector.open( path, Connector.READ_WRITE );
            if( !fconn.exists() )
                fconn.mkdir();
            fconn.close();
            
            fconn = (FileConnection)Connector.open(path + file, Connector.READ_WRITE );
            if( !fconn.exists() )
                fconn.create();

            fconn.close();
        }
        catch( IOException ioe )
        {
            System.out.println( "IOException: " + ioe.getMessage() );
        }
        catch( SecurityException se )
        {
            System.out.println( "Security exception:" + se.getMessage() );
        }
        finally
        {
            System.out.println("created Directory");
        }
    }
    
    public static void DEBUG_showFilesystem( String path, String file )
    {
        try
        {
            FileConnection fconn = (FileConnection)Connector.open( path, Connector.READ_WRITE );
            if( !fconn.exists() )
                fconn.mkdir();
            fconn.close();
            
            fconn = (FileConnection)Connector.open(path + file, Connector.READ_WRITE );
            if( !fconn.exists() )
                fconn.create();

            fconn.close();
        }
        catch( IOException ioe )
        {
            System.out.println( "IOException: " + ioe.getMessage() );
        }
        catch( SecurityException se )
        {
            System.out.println( "Security exception:" + se.getMessage() );
        }
        finally
        {
            System.out.println("created Directory");
        }
    }

    public static void savePersonsToFS( String filename, String text )
    {
        try
        {
            byte data[] = text.getBytes();
            FileConnection fconn = (FileConnection)Connector.open( filename, Connector.READ_WRITE );
            if( !fconn.exists() )
                fconn.mkdir();
            fconn.close();
            fconn = (FileConnection)Connector.open( filename, Connector.READ_WRITE );
            if( !fconn.exists() )
                fconn.create();

            OutputStream ops = fconn.openOutputStream();
            ops.write( data );
            ops.close();
            fconn.close();
        }
        catch( IOException ioe )
        {
            System.out.println( "IOException: " + ioe.getMessage() );
        }
        catch( SecurityException se )
        {
            System.out.println( "Security exception:" + se.getMessage() );
        }
    }
    
    public static void deleteFile(String filename)
    {
    	try
        {        	
        	FileConnection fconn = (FileConnection)Connector.open( IDataModelConstants.ROOT_PATH1 + IDataModelConstants.PERSONS_PATH + filename, Connector.READ_WRITE );
        	if(fconn.exists())
        	{
        		fconn.setWritable(true);
        		fconn.delete();
        		fconn.close();
        	}
    		fconn.close();
        	
        	fconn = (FileConnection)Connector.open(IDataModelConstants.ROOT_PATH2 + IDataModelConstants.PERSONS_PATH  + filename, Connector.READ_WRITE );
        	if(fconn.exists())
        	{
        		fconn.setWritable(true);
        		fconn.delete();
        		fconn.close();
        	}
    		fconn.close();      	
        }
        catch( IOException ioe )
        {
        	ioe.printStackTrace();
        }
        catch( SecurityException se )
        {
            System.out.println( "Security exception:" + se.getMessage() );
        }
    }
    
    public static String saveNewPersonsToFS(String filename, Person person)
    {
    	String result = "";
        try
        {
        	String root = "";
        	FileConnection fconn = (FileConnection)Connector.open( IDataModelConstants.ROOT_PATH1, Connector.READ );
        	if( fconn.exists() )
        		root = IDataModelConstants.ROOT_PATH1;
        	else
        		root = IDataModelConstants.ROOT_PATH2;
        	fconn.close();
        	
        	fconn = (FileConnection)Connector.open( root + IDataModelConstants.PERSONS_PATH );
        	if( !fconn.exists() )
                fconn.mkdir();
        	
        	fconn = (FileConnection)Connector.open( root + IDataModelConstants.PERSONS_PATH + filename, Connector.READ_WRITE );
        	if( !fconn.exists() )
                fconn.create();

            OutputStream ops = fconn.openOutputStream();
            Enumeration keys = person.getInformationEnumeration();
            String connector = "=";
            String endOfLine = "\n";
            String tempPersonInformation = "";
            while(keys.hasMoreElements())
            {
            	String tempKey = keys.nextElement().toString();
            	tempPersonInformation = person.getInformation(tempKey);
            	
            	ops.write(tempKey.getBytes());
            	ops.write(connector.getBytes());
            	ops.write(tempPersonInformation.getBytes());
            	ops.write(endOfLine.getBytes());
            }
            ops.close();
            fconn.close();
        }
        catch( IOException ioe )
        {
            System.out.println( "IOException: " + ioe.getMessage() );
            result = "IOException: " + ioe.getMessage() ;
        }
        catch( SecurityException se )
        {
            System.out.println( "Security exception:" + se.getMessage() );
            result = "Security exception: " + se.getMessage() ;
        }
        return result;
    }

    public static Enumeration getCsvListFromFS()
    {
    	Enumeration csvList = null;
        try
        {                
            String root = "";
        	FileConnection fconn = (FileConnection)Connector.open( IDataModelConstants.ROOT_PATH1, Connector.READ );
        	if( fconn.exists() )
        		root = IDataModelConstants.ROOT_PATH1;
        	else
        		root = IDataModelConstants.ROOT_PATH2;
        	fconn.close();
            
        	fconn = (FileConnection)Connector.open( root+ IDataModelConstants.CSV_PATH, Connector.READ );
            if( !fconn.exists() )
	            return null;
            
            csvList = fconn.list("*.csv", true);
            fconn.close();
        }
        catch( IOException ioe )
        {
            System.out.println( "IOException: " + ioe.getMessage() );
        }
        catch( SecurityException se )
        {
            System.out.println( "Security exception:" + se.getMessage() );
        }
        if(csvList.hasMoreElements())
        	return csvList;
        else
        	return null;
    }
    
    public static Vector getPersonsToSync(String filename)
    {
    	Vector personVector = new Vector();
        try
        {    
        	/*String root = "";
        	FileConnection fconn = (FileConnection)Connector.open( IDataModelConstants.ROOT_PATH1, Connector.READ );
        	if( fconn.exists() )
        		root = IDataModelConstants.ROOT_PATH1;
        	else
        		root = IDataModelConstants.ROOT_PATH2;
        	fconn.close();*/
            
        	//fconn = (FileConnection)Connector.open( root + IDataModelConstants.CSV_PATH + filename, Connector.READ );
        	FileConnection fconn = (FileConnection)Connector.open("file:///" + filename, Connector.READ );
            if( !fconn.exists() )
	            return null;
            
            String line;
            int row = 0;
            int col = 0;
            int i = 0;
            // relevant attributes for friendbox
            String rela[] = {"First Name", "Last Name", "Home Street", "Home City", "Home Postal Code", "Home Phone", "Mobile Phone", "Business Phone"};
            Vector aCol = new Vector();
            Vector aKey = new Vector();
            Person currentPerson = new Person();

            DataInputStream dis = fconn.openDataInputStream();

            while( !"".equals( line = readLine( dis ) ) )
            {
            	String[] temparr = split(line, ';', false);
            	// get relevant attribute keys & related col from first row
            	if( row == 0 )
            	{
            		for( col = 0; col < temparr.length; col++ )
            		{
            			for( i = 0; i < rela.length; i++ )
            			{
                			if( temparr[col].equals(rela[i]) )
                			{
                				aCol.addElement(new Integer(col));
                				aKey.addElement(temparr[col]);
                				// e.g.  aKey = "First Name", aCol = 0 
                			}
            			}
            		}
            	}
            	// write all relevant cols + related attribute keys into currentPerson
            	else 
            	{
            		for( col = 0; col < temparr.length; col++ )
            		{
            			for( i = 0; i < aCol.size(); i++ )
            			{
            				if( aCol.elementAt(i).equals(new Integer(col)) )
            					currentPerson.putInformation(getPersonKey( aKey.elementAt(i).toString() ), temparr[col]);
            			}
            		}
                	// add currentPerson to personVector
               		personVector.addElement(currentPerson);
            	}
            	currentPerson = new Person();
            	row++;
            }
            dis.close();
            fconn.close();
        }
        catch( IOException ioe )
        {
            System.out.println( "IOException: " + ioe.getMessage() );
        }
        catch( SecurityException se )
        {
            System.out.println( "Security exception:" + se.getMessage() );
        }
        return personVector;
    }    
    
    private static String getPersonKey(String csvKey)
    {
    	String pKey = new String();

    	if( csvKey.equals("First Name") )		pKey = "person.firstname";
    	if( csvKey.equals("Last Name") )		pKey = "person.lastname";		
    	if( csvKey.equals("Home Street") )		pKey = "person.street";				
    	if( csvKey.equals("Home City") )		pKey = "person.city";
    	if( csvKey.equals("Home Postal Code") )	pKey = "person.zip";
    	if( csvKey.equals("Home Phone") )		pKey = "person.tel2";
    	if( csvKey.equals("Mobile Phone") )		pKey = "person.tel1";
    	if( csvKey.equals("Business Phone") )	pKey = "person.tel3";
    	
    	return pKey;
    }

    public static void loadPersonsFromFS( IPersonListener listener )
    {
        try
        {    
            FileConnection fconn = (FileConnection)Connector.open( IDataModelConstants.ROOT_PATH1 + IDataModelConstants.PERSONS_PATH , Connector.READ );
            if( !fconn.exists() )
            {
        		fconn.close();
                fconn = (FileConnection)Connector.open( IDataModelConstants.ROOT_PATH2 + IDataModelConstants.PERSONS_PATH , Connector.READ );
            }
            if( !fconn.exists() )
            {
        		fconn.close();
                return;
            }
            String line;
            String name;
            String info;
            Enumeration e = fconn.list();
            Person currentPerson = null;
            while( e.hasMoreElements() )
            {
                fconn.setFileConnection( (String)e.nextElement() );
                DataInputStream dis = fconn.openDataInputStream();
                if (currentPerson != null)
                {
                    currentPerson.setNext( new Person());
                    currentPerson.getNext().setPrev( currentPerson );
                    currentPerson = currentPerson.getNext();
                }
                else
                    currentPerson = new Person();
                listener.newPersonAction( IPersonListener.ACTION_NEWPERSON, currentPerson );
                while( !"".equals( line = readLine( dis ) ) )
                {
                    name = line.substring( 0, line.indexOf( '=' ) );
                    info = line.substring( line.indexOf( '=' ) + 1 );
                    currentPerson.putInformation( name, info );
                    listener.newPersonAction( IPersonListener.ACTION_NEWDETAIL, currentPerson );
                }
                fconn.close();
                fconn = (FileConnection)Connector.open( IDataModelConstants.ROOT_PATH1 + IDataModelConstants.PERSONS_PATH , Connector.READ );
                if( !fconn.exists() )
                {
                	fconn.close();
                	fconn = (FileConnection)Connector.open( IDataModelConstants.ROOT_PATH2 + IDataModelConstants.PERSONS_PATH , Connector.READ );
                }
                dis.close();
            }
            fconn.close();
        }
        catch( IOException ioe )
        {
            System.out.println( "IOException: " + ioe.getMessage() );
        }
        catch( SecurityException se )
        {
            System.out.println( "Security exception:" + se.getMessage() );
        }
    }    
    
    private static String readLine( DataInputStream isr ) throws IOException
    {
        StringBuffer sb = new StringBuffer();

        int i;
        while( (i = isr.read()) != -1 )
        {
            if( (char)i == '\n' )
                break;
            sb.append( (char)i );
        }
        return sb.toString();
    }

    public final static String[] split(String toSplit,char delim,boolean ignoreEmpty)
    {
    	StringBuffer buffer = null;
    	Stack stringStack = null;
    	
        buffer = new StringBuffer();
        stringStack = new Stack();
        for(int i = 0;i<toSplit.length();i++)
        {
            if(toSplit.charAt(i) != delim)
            {
               
                buffer.append((char)toSplit.charAt(i));
            }
            else
            {
                if(buffer.toString().trim().length() == 0 && ignoreEmpty)
                {
                   
                }
                else
                {
                    stringStack.addElement(buffer.toString());
                }
                buffer = new StringBuffer();
            }
        }
       
        if(buffer.length() != 0)
            stringStack.addElement(buffer.toString());
       
       
        String [] split = new String[stringStack.size()];
        for(int i = 0;i<split.length;i++)
        {
            split[split.length-1-i] = (String)stringStack.pop();
        }
       
        stringStack = null;
        buffer = null;
        return split;
    }
}
